#ifndef _TYPES_H_
#define _TYPES_H_

#define MAX_NAME_LEN    128     
#define GUA_MAGIC_NUM           0x12345678  
#define BLOCK_SIZE             1024
#define IO_SIZE                512
#define INODE_BLOCK_NUM        1
#define DATA_BLOCK_NUM         6
#define GUAFS_ROOT_INO            0


#define ROUND_DOWN(value, round)    (value % round == 0 ? value : (value / round) * round)
#define ROUND_UP(value, round)      (value % round == 0 ? value : (value / round + 1) * round)
#define BLKS_SZ(blks)               (blks * BLOCK_SIZE)
#define GUAFS_INO_OFS(ino)      (super.inode_offset + ino * BLKS_SZ(INODE_BLOCK_NUM))
#define GUAFS_DATA_OFS(dno)     (super.data_offset + dno * BLKS_SZ(DATA_BLOCK_NUM))

typedef enum file_type {
    REG_FILE,
    DIR
} FILE_TYPE;

struct custom_options {
	const char*        device;
};

struct guafs_super {
    uint32_t magic;
    int      fd;
    int      disk_sz;
    int      usage_sz;

    int      max_ino;                     //最大文件数
    int      map_inode_blks;              // inode位图占用的块数
    int      map_inode_offset;            // inode开始的偏移
    int      map_data_blks;               // data位图占用的块数
    int      map_data_offset;             // data位图在磁盘上的偏移

    uint8_t* inode_map;
    uint8_t* data_map;

    int      inode_offset;
    int      data_offset;
    int     is_mount;
    struct   guafs_dentry* root_dentry;  
    int cur_inode_num;
};

struct guafs_inode {
    int                ino;
    int                size;               // 文件已占用空间
    int                link;               // 链接数
    FILE_TYPE          ftype;              // 文件类型（目录类型、普通文件类型）
    int                dir_cnt;            // 如果是目录类型文件，下面有几个目录项
    struct guafs_dentry* my_dentry;         //该inode对应的dentry
    struct guafs_dentry* child_dentrys;    //文件夹类型下的子dentry，链表组织
    int                datablk_pointer[DATA_BLOCK_NUM];   // 数据块指针（可固定分配）
};

struct guafs_dentry {
    char     fname[MAX_NAME_LEN];
    struct guafs_dentry* parent;   
    struct guafs_dentry* brother;
    struct guafs_inode* inode;               //指向本dentry的inode
    FILE_TYPE          ftype;                         // 指向的ino文件类型
    int                ino;                           // 指向的ino号
    int                valid;  
};


static inline struct guafs_dentry* new_dentry(char * fname, FILE_TYPE ftype) {
    struct guafs_dentry * dentry = (struct guafs_dentry *)malloc(sizeof(struct guafs_dentry));
    memset(dentry, 0, sizeof(struct guafs_dentry));
    memcpy(dentry->fname,fname,strlen(fname));
    dentry->ftype   = ftype;
    dentry->ino     = -1;
    dentry->inode   = NULL;
    dentry->parent  = NULL;
    dentry->brother = NULL;   
    dentry->valid   = 1;                                         
}


struct guafs_super_d {
    uint32_t magic;
    int      usage_sz;
    int      max_ino;                     //最大文件数
    int      map_inode_blks;              // inode位图占用的块数
    int      map_inode_offset;            // inode开始的偏移
    int      map_data_blks;               // data位图占用的块数
    int      map_data_offset;             // data位图在磁盘上的偏移

    int      inode_offset;
    int      data_offset;
    int cur_inode_num;
};

struct guafs_inode_d{
    int                ino;
    int                size;               // 文件已占用空间
    FILE_TYPE          ftype;              // 文件类型（目录类型、普通文件类型）
    int                dir_cnt;            // 如果是目录类型文件，下面有几个目录项
    int                datablk_pointer[6];   // 数据块指针（可固定分配）
};


struct guafs_dentry_d {
    char     fname[MAX_NAME_LEN];
    FILE_TYPE          ftype;                         // 指向的ino文件类型
    int                ino;                           // 指向的ino号
    int                valid;  
};
#endif /* _TYPES_H_ */  